package com.fushenlan.commons;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @author PC
 * @title: ExtRedisTemplate
 * @projectName SpringBootDemo
 * @description: TODO
 * @date 2022/1/21 10:40
 */
@Component
public class ExtRedisTemplate {
    //    @Resource(
//            name = "easyRedisTemplate"
//    )
    private RedisTemplate redisTemplate;
    @Autowired
    private RedisProps redisProps;

    public ExtRedisTemplate() {
    }

    public String generateKey(DataType type, String region, String key) {
        return this.redisProps.getActive() + ":" + this.redisProps.getAppName() + ":" + type.getValue() + ":" + key;
    }

    public Object get(Object key) {
        return this.redisTemplate.opsForValue().get(key);
    }

    public void set(Object key, Object value, long expire, TimeUnit unit) {
        if (expire > 0L) {
            this.redisTemplate.opsForValue().set(key, value, expire, unit);
        }
    }

    private void sleep(long millis) {
        try {
            Thread.sleep((millis));
        } catch (Exception e) {

        }
    }

    public boolean tryLock(Object key, long expireMilliseconds, long retryTimes) {
        for (long i = 1L; i <= retryTimes; ++i) {
            if (this.tryLock(key, expireMilliseconds)) {
                return true;
            }
            if (i != retryTimes) {
                this.sleep(1000L);
            }
        }
        return false;
    }

    public boolean tryLock(Object key, long expireMilliseconds) {
        String expireAt = String.valueOf(System.currentTimeMillis() + expireMilliseconds + 1L);
        Boolean acquire = this.redisTemplate.opsForValue().setIfAbsent(key, expireAt, expireMilliseconds, TimeUnit.MILLISECONDS);
        return acquire != null ? acquire : false;
    }

    public boolean delLock(Object key) {
        return this.redisTemplate.delete(key);
    }

    public boolean delete(Object key) {
        return this.redisTemplate.delete(key);
    }
}
